﻿namespace Wolfpack.Contrib.Checks.Processes
{
    using System;
    using System.Linq;
    using System.Management;
    using Wolfpack.Core;
    using Wolfpack.Core.Interfaces;
    using Wolfpack.Core.Interfaces.Entities;

    public class ProcessCheckConfig : PluginConfigBase
    {
        public string ProcessName { get; set; }
        public string NumberOfFailures { get; set; }
    }

    public class ProcessCheck : IHealthCheckPlugin
    {

        public readonly PluginDescriptor MyIdentity;
        public readonly string MyWmiNamespace;
        public readonly ProcessCheckConfig myConfig;
        public int CountOfFailures;
        public int MaxFailures;
        public ManagementScope wmiScope;

        public Status Status { get; set; }

        public PluginDescriptor Identity
        {
            get { return MyIdentity; }
        }

        public ProcessCheck(ProcessCheckConfig config)
        {
            myConfig = config;

            MyWmiNamespace = string.Format(@"\\localhost\root\cimv2");

            MyIdentity = new PluginDescriptor
            {
                Description =
                    string.Format("Checks for the existance of process '{0}' and delays report until {1} failures are found.", myConfig.ProcessName,
                                  myConfig.NumberOfFailures),
                TypeId = new Guid("F38C18C8-892A-490d-982C-40D524103AE3"),
                Name = myConfig.FriendlyId
            };

            this.MaxFailures = Int16.Parse(this.myConfig.NumberOfFailures);
            wmiScope = new ManagementScope(MyWmiNamespace);
        }



        public void Execute()
        {
            Logger.Debug("Querying wmi namespace {0}...", MyWmiNamespace);

            // set up the query and execute it
            var wmiQuery = new ObjectQuery("Select * from Win32_Process");
            var wmiSearcher = new ManagementObjectSearcher(wmiScope, wmiQuery);
            var wmiResults = wmiSearcher.Get();
            var processes = wmiResults.Cast<ManagementObject>();

            var matches = from process in processes
                          where
                              (string.Compare(process["Name"].ToString(), myConfig.ProcessName,
                                              StringComparison.InvariantCultureIgnoreCase) == 0)
                          select process;

            if (matches.Count() == 0)
            {
                CountOfFailures++;
            }
            else
            {
                CountOfFailures = 0;
            }

            var msg = new HealthCheckData
                            {
                                Identity = Identity,
                                Info = string.Format("Process '{0}' failed for a total of '{1}' times",
                                                    myConfig.ProcessName,
                                                    this.CountOfFailures),
                                Result = (CountOfFailures < MaxFailures),
                                ResultCount = CountOfFailures
                            };

            Messenger.Publish(msg);


            Logger.Debug("HealthCheck: '{0}'. Done checking process: '{1}.' Current Count of Failures: '{2}'. MaxFailureNumber: '{3}'.",
                this.myConfig.FriendlyId,
                this.myConfig.ProcessName,
                CountOfFailures.ToString(),
                this.myConfig.NumberOfFailures);
        }

        public void Initialise()
        {

        }
    }
}